package com.lhg.netty.c4;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Server {
    public static void main(String[] args) throws IOException {

        Selector selector = Selector.open();

        ByteBuffer buffer = ByteBuffer.allocate(16);

        ServerSocketChannel ssc = ServerSocketChannel.open();

        ssc.configureBlocking(false);
        // SelectionKey 事件发生后，知道那个channel发生的事件
        /**
         * accept - 有请求
         * connect 客户端 建立连接
         * read 可读
         * write 可写
         */
        SelectionKey ssckey = ssc.register(selector, 0, null);
        System.out.println(ssckey);
        //关注 accept 事件
        ssckey.interestOps(SelectionKey.OP_ACCEPT);

        ssc.bind(new InetSocketAddress(8888));
        List<SocketChannel> channels = new ArrayList<>();
        while (true){
            // 没有事件先休息，有事件恢复
            // 事件未处理时，不阻塞
            selector.select();
            System.out.println("xxxxxx");

            Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
            while (iter.hasNext()){
                SelectionKey key = iter.next();

                // 处理key时，要从 selectedKeys 中移除，否则会出现异常
                iter.remove();
                System.out.println(key);
                if (key.isAcceptable()) {
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel sc = channel.accept();
                    sc.configureBlocking(false);
                    // att 附件
                    ByteBuffer buffer1 = ByteBuffer.allocate(1024);
                    SelectionKey sckey = sc.register(selector, 0, buffer1);
                    sckey.interestOps(SelectionKey.OP_READ);
                }else if (key.isReadable()){
                    try {
                        SocketChannel channel = (SocketChannel) key.channel();
                        //
                        ByteBuffer buffer1 = (ByteBuffer) key.attachment();
                        int read = channel.read(buffer1);
                        // 正常断开
                        if (read==-1){
                            key.cancel();
                        }

                        buffer1.flip();
                        System.out.println(Charset.defaultCharset().decode(buffer1));
                    } catch (IOException e) {
                        System.out.println(key);
                        key.cancel();
                        e.printStackTrace();
                    }

                }


            }

            /* 非阻塞方式

            SocketChannel sc = ssc.accept();
            if (sc!=null){
                System.out.println("connected");
                sc.configureBlocking(false); // 设置非阻塞
                channels.add(sc);
            }

            for (SocketChannel channel : channels
                    ) {
                int read = channel.read(buffer);
                if (read >0) {
                    buffer.flip();
                    System.out.println(Arrays.toString(buffer.array()));
                    buffer.clear();
                }
            }

            */

        }


    }
}
